import { IViewComponentProps } from "@/Factory";
import { useOpenEditor } from "@/hooks/Workspaces/useOpenEditor";
import { contacts_mgr, IContactItem } from "@/mgr";
import { Paths } from "@/paths";
import { LoadingOutlined, UserAddOutlined } from "@ant-design/icons";
import { Button, Dropdown, Flex, Input, Popover, Select, Typography } from "antd";
import classNames from "classnames";
import QueryString from "qs";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useImmer } from "use-immer";
import { ContactType } from "../../constants/ContactType";
import { FriendType } from "../../constants/FriendType";
import { FlexHeader, ListEmpty } from "../_BaseView/FlexRoot";
import { ContactItem } from "./ContactItem";
import styles from "./styles.module.scss";
import { List } from "../_BaseView/List";
import { ContactEditModal } from "../ContactEditView";

interface IData {
  list: IContactItem[],
  loading?: boolean,
  error?: any;
}
const init_data: IData = { list: [] }

interface IParams {
  keyword?: string
  refresh_flag: number;
}
const init_params: IParams = { refresh_flag: 1 }
export default function ContactsView(props: IViewComponentProps) {
  const { actived = true } = props
  const [{ list, loading, error }, set_data] = useImmer<IData>(init_data)
  const [{ keyword, refresh_flag }, set_params] = useImmer<IParams>(init_params)
  const [contact_type, set_contact_type] = useState<ContactType.Value | undefined>(ContactType.Value.联系人);
  const [friend_type, set_friend_type] = useState<FriendType.Value | undefined>(FriendType.Value.仅好友);

  const _list = useMemo(() => {
    const is_friend_type_met = (v: IContactItem) => {
      switch (friend_type) {
        case FriendType.Value.仅好友:
          return v.isFriend
        case FriendType.Value.非好友:
          return !v.isFriend
      }
      return true
    }
    return list.filter(v => ContactType.is_username_met(v.userName, contact_type) && is_friend_type_met(v))
  }, [contact_type, list, friend_type])

  useEffect(() => {
    set_data({
      list: contacts_mgr.list,
      error: contacts_mgr.error,
      loading: contacts_mgr.loading,
    })
    contacts_mgr.keyword = keyword;
    contacts_mgr.stop();
    contacts_mgr.start();
    let tid: ReturnType<typeof setTimeout> | null = null;
    const cancel = contacts_mgr.callbacks.add({
      on_loading_changed(_, is_loading) {
        if (tid) clearTimeout(tid)
        tid = setTimeout(() => {
          set_data(o => { o.loading = is_loading })
          tid = null;
        }, 1000)
      },
      on_list_change(mgr) {
        set_data(o => {
          o.list = mgr.list
          o.error = mgr.error
        })
      },
    })
    return () => {
      if (tid) clearTimeout(tid)
      contacts_mgr.keyword = void 0;
      cancel()
    }
  }, [refresh_flag, keyword, contacts_mgr])

  const open_editor = useOpenEditor();
  const [editing_item, set_editing_item] = useImmer<{ open?: boolean, data?: IContactItem }>({});
  const render_item = (item: IContactItem) => {
    const edit = () => set_editing_item({ open: true, data: item })
    const on_click = (e: React.MouseEvent) => {
      const title = item?.remark || item?.nickName || item.nickName || item.userName
      const query = QueryString.stringify({ ...item, title: title })
      const path = Paths.All.LocalChat + '?' + query
      open_editor(path)
      e.stopPropagation();
      e.preventDefault();
    }
    return (
      <Dropdown
        trigger={['contextMenu']}
        menu={{ items: [{ key: '_', label: '修改信息', onClick: () => set_editing_item({ open: true, data: item }) }] }}>
        <ContactItem
          item={item}
          key={item.userName}
          onClick={on_click}
          is_local
          actions={({ item: { phone }, loading, }) => <>
            {
              phone ? null :
                <Button shape='circle' disabled={loading} type='text' size='small' onClick={edit} title='设置联系人信息'>
                  {loading ? <LoadingOutlined /> : <UserAddOutlined />}
                </Button >
            }
          </>} />
      </Dropdown>
    )
  }

  return (
    <Flex vertical className={classNames(styles.contacts_view, { [styles.inactived]: !actived })}>
      <FlexHeader vertical align='stretch'>
        <Input.Search
          placeholder="关键词搜索"
          size='small'
          onBlur={e => set_params(o => {
            o.keyword = e.target.value || void 0;
            o.refresh_flag++
          })}
          onSearch={v => set_params(o => {
            o.keyword = v; o.refresh_flag++
          })} />
        <Flex justify='space-between'>
          <Typography.Text type='secondary'>
            {[`数量 ${_list.length}`, ContactType.label(contact_type), FriendType.label(friend_type)].filter(Boolean).join(', ')}
          </Typography.Text>
          <Flex gap={10}>
            {loading ? <LoadingOutlined /> : null}
            <Popover
              content={
                <Flex vertical gap={5}>
                  <Flex gap={5} align='center'>
                    <Typography.Text type='secondary'>是否好友</Typography.Text>
                    <Select value={friend_type} onChange={set_friend_type} options={FriendType.options}
                      allowClear placeholder='是否好友' style={{ width: 120 }} size='small' />
                  </Flex>
                  <Flex gap={5} align='center'>
                    <Typography.Text type='secondary'>联系类型</Typography.Text>
                    <Select value={contact_type} onChange={set_contact_type} options={ContactType.options}
                      allowClear placeholder='联系类型' style={{ width: 120 }} size='small' />
                  </Flex>
                </Flex>
              }
              forceRender>
              <Typography.Text>筛选</Typography.Text>
            </Popover>
          </Flex>
        </Flex>
      </FlexHeader>

      <List
        virtual={_list.length > 100}
        data={_list}
        itemHeight={71}
        itemKey="userName"
        others={<ListEmpty show={!_list.length} description='暂无联系人' />}>
        {render_item}
      </List>

      <ContactEditModal
        open={editing_item.open}
        onCancel={() => set_editing_item(o => { o.open = false })}
        afterClose={() => set_editing_item(o => { o.data = void 0 })}
        data={editing_item.data}
        on_success={(edited) => {
          set_editing_item(o => { o.open = false })
          set_data(o => {
            const ret = [...o.list];
            const index = ret.findIndex(a => a.account === edited.account && a.userName === edited.userName)
            if (index >= 0) ret[index] = edited;
            o.list = ret
          })
        }} />
    </Flex>
  )
}
